package references

import (
	"jvm/nzpJvm/instructions/base"
	"jvm/nzpJvm/runtime_area"
	"jvm/nzpJvm/runtime_area/heap"
)

// anewarray指令用来创建引用类型数组。只支持创建一维数组
type A_NEW_ARRAY struct {
	// newarray指令的第一个操作数是一个对常量池的索引，可以在常量池中定位到一个类的符号引用，标识数组的类型，从字节码中获取
	base.Index16Instruction
}

func (self *A_NEW_ARRAY) Execute(frame *runtime_area.Frame) {
	constantPool := frame.Method().Class().ConstantPool()
	classRef := constantPool.GetConstant(self.Index).(*heap.ClassRef)
	// 此引用类型数组的组件类型
	componentType := classRef.ResolveClass()

	stack := frame.OperandStack()
	// newarray的第二个操作数是count，表示数组长度，从操作数栈中弹出
	arrayLength := stack.PopInt()
	if arrayLength < 0 {
		panic("java.lang.NegativeArraysSizeException")
	}
	// 将组件类型转换为数组类型
	arrayType := componentType.ArrayClass()
	// 创建指定的长度的基本类型数组对象
	arrayObject := arrayType.NewArray(uint(arrayLength))
	// 新的数组对象入栈
	stack.PushRef(arrayObject)
}
